﻿#include"stdafx.h"
#include"ServerDB.h"

int  ServerDB::Table_update(const char*tname,string db, vector<insert_model>fields, vector<struct_where>where, string &msg) {
	cur_db = db.c_str();
	if (cur_db == "") {
		msg = "Please choose a database !";
		return 0;
	}
	//表名合法性
	CString  tbPath; tbPath = L"data\\" + cur_db + L"\\" + cur_db + L".tb";
	if (!IsTable(tbPath, tname)) {
		msg = "Incorrect table name !";
		return false;
	}
	CString DBPath; 
	CString Ctname; 
	Ctname = tname; 
	bool index = false;
	DBPath = L"data\\" + cur_db + L"\\" + Ctname + L".tdf";
	Table_Tdf tdf; 
	vector<Table_Tdf>vec_tdf;
	file.Open(DBPath, CFile::modeRead | CFile::typeBinary, NULL);
	while (file.Read(&tdf, sizeof(tdf))) {
		vec_tdf.push_back(tdf);
	}
	file.Close();

	Table_Tdf Ttdf = vec_tdf.back();
	int lenth = Ttdf.order + Ttdf.param;

	// 判断字段是否合法
	for (unsigned int i = 0; i < fields.size(); i++) {
		for (unsigned int j = 0; j < vec_tdf.size(); j++) {
			if (strcmp(vec_tdf[j].name, fields[i].key.c_str()) == 0) {
				fields[i].pos = vec_tdf[j].order;
				fields[i].mmSize = vec_tdf[j].param;
				fields[i].index = vec_tdf[j].index;
				fields[i].type = vec_tdf[j].type;
				//unique完整维护
				for (int k = 0; k< 5; k++) {
					string intergrity = vec_tdf[j].intergrities[k];
					if (intergrity == "o")
						break;
					if (intergrity == "7" || intergrity == "6") {
						if (!IsUnique(L"data\\" + cur_db + L"\\" + Ctname + L".trd"
							, vec_tdf[j].type, vec_tdf[j].order, lenth, vec_tdf[j].param, fields[i].value)) {
							msg = fields[i].key;
							msg += " is not unique！";
							return false;
						}
					}
				}
				//判断日期的合法性
				if (fields[i].type == "5" && !IsDateValid(fields[i].value.c_str())) {
					msg = "Invalid date in field!";
					return 0;
				}

				index = false;
			}
		}
		if (index) {
			msg = "Invalid column ";
			return 0;
		}
		index = true;
	}

	//判断where字段是否合法
	index = true;
	for (unsigned int i = 0; i < where.size(); i++) {
		for (unsigned int j = 0; j < vec_tdf.size(); j++) {
			if (strcmp(vec_tdf[j].name, where[i].key.c_str()) == 0) {
				where[i].pos = vec_tdf[j].order;
				where[i].size = vec_tdf[j].param;
				where[i].index = vec_tdf[j].index;
				where[i].type = vec_tdf[j].type;
				if (where[i].type == "5" && !IsDateValid(where[i].value.c_str())) {
					msg = "Invalid date in where";
					return 0;
				}
				index = false;
			}
		}
		if (index) {
			msg = "Invalid column in where";
			return 0;
		}
		index = true;
	}

	DBPath = L"data\\" + cur_db + L"\\" + Ctname + L".trd";

	file.Open(DBPath, CFile::modeReadWrite | CFile::typeBinary, NULL);
	//判断是否有可用的索引
	struct_where result;
	if (HasAvilableIndex(where, result)) {
		vector<int>indexPoss;
		string path = "data\\" + db + "\\" + tname + "_" + result.key + ".tid";
		string judge = db + "_" + tname + "_" + result.key;
		indexPoss = indexM.select(path, judge, result);
		if (indexPoss.size() == 0) {
			file.Close();
			msg = "Null Column has changed !";
			return 0;
		}
		for (unsigned int i = 0; i < indexPoss.size(); i++) {
			Traversal(file, indexPoss[i], fields, where);
		}
	}
	else {
		//没有可用的索引
		int offset = 0;
		while (file.GetLength()>offset) {
			Traversal(file, offset, fields, where);
			offset += lenth;
		}
	}
	file.Close();
	//生成新的索引
	string tpath = "data\\" + db + "\\" + tname;
	for (unsigned int i = 0; i < fields.size(); i++) {
		if (fields[i].index) {
			int size = fields[i].mmSize;
			string auth = db + "_" + tname + "_" + fields[i].key;
			indexM.ReProduceIndex(tpath, fields[i].key,auth,fields[i].pos,lenth, size);
		}
	}
	msg = "successful !";
	return 1;
}